package sc.nio;

import java.util.LinkedList;
import java.util.List;

/**
 * Threaded socket server, that uses a Selector to multiplex SocketChannels.
 *
 * @author stephencarmody@gmail.com Stephen Carmody
 */
public abstract class NioHandler implements Runnable
{	
	// Queue of received SocketChannels
	private List<NioChannelData> pending = new LinkedList<NioChannelData>();
	
	/**
	 * Creates an instance of NioReader.
	 */
	public NioHandler()
	{
	}

	/**
	 * Receives a channel with data.
	 * 
	 * @param channeldata
	 * 			An NioChannelData instance
	 */
	public void receive(NioChannelData channeldata)
	{
		synchronized (pending)
		{
			pending.add(channeldata);
			pending.notify();
		}
	}

	/**
	 * Thread main loop.
	 * - Waits for messages to be queued 
	 * - Removes messages from queue
	 * - Calls read(SocketChannel) to act on the channel data appropriately
	 */
	public void run()
	{
		NioChannelData channeldata;

		while (true)
		{
			// Wait for data to become available
			synchronized (pending)
			{
				while (pending.isEmpty())
					try {pending.wait();} catch (InterruptedException e) {}
				channeldata = pending.remove(0);
			}
			
			this.read(channeldata);
		}
	}
		
	/**
	 * Handles the given client message appropriately.
	 *  
	 * @param channeldata
	 * 			An NioChannelData instance
	 */
	abstract protected void read(NioChannelData channeldata);
}
